﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TeamFoundation.ContinuousMerge.Tasks
{
    /// <summary>
    /// Represents a posted task.
    /// </summary>
    public abstract class TaskPost : IDisposable
    {
        private volatile bool _hasExecuted;
        /// <summary>
        /// Gets a value indicating whether the task has executed.
        /// </summary>
        public bool HasExecuted
        {
            get
            {
                return _hasExecuted;
            }
        }

        private volatile bool _isDisposed;
        /// <summary>
        /// Gets a value indicating whether the task has been disposed.
        /// </summary>
        public bool IsDispoed
        {
            get
            {
                return _isDisposed;
            }
        }
        

        /// <summary>
        /// Executes the task against the runtime.
        /// </summary>
        /// <param name="runtime">The runtime.</param>
        public void Execute(Runtime runtime)
        {
            if (_isDisposed)
                return;

            if (_hasExecuted)
                return;
            _hasExecuted = true;
            OnExecute(runtime);
            Dispose();
        }

        /// <summary>
        /// Executes the task against the runtime.
        /// </summary>
        /// <param name="runtime">The runtime.</param>
        protected abstract void OnExecute(Runtime runtime);

        #region IDisposable Members

        /// <summary>
        /// Finalizer.
        /// </summary>
        ~TaskPost()
        {
            if (_isDisposed)
                return;
            _isDisposed = true;

            Dispose(false);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Disposes of the object and any related resources.
        /// </summary>
        public void Dispose()
        {
            if (_isDisposed)
                return;
            _isDisposed = true;

            Dispose(true);
        }

        /// <summary>
        /// Disposes of the object and any related resources.
        /// </summary>
        /// <param name="disposing">Whether the dispose method was invoked (true) or the finalizer was invoked (false).</param>
        protected virtual void Dispose(bool disposing)
        {

        }

        #endregion
    }
}
